package orchestration

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
	"github.com/gophercloud/gophercloud"
	"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
	"openstack_api/client"
	"openstack_api/exceptions"
)

type Flavor struct {
	// ID is the flavor's unique ID.
	flavors.CreateOpts
}

func (f Flavor) getClient() (serviceClient *gophercloud.ServiceClient) {
	serviceClient = client.GetServerClient()
	return
}

func (f Flavor) errRet(c *gin.Context, code int, message interface{}) {
	c.JSON(code, gin.H{
		"code":    code,
		"message": message,
	})
}

func (f Flavor) CreateFlavor(c *gin.Context) {
	serverClient := f.getClient()
	_, ok := binding.Validator.Engine().(*validator.Validate)
	if ok != false {
	}

	//if ok {
	//	//err := validate.RegisterValidation("resources", checkResources)
	//	//if err != nil {
	//	//	return
	//	//}
	//}
	//_ = zhs.RegisterDefaultTranslations(validate, trans)
	err := c.ShouldBindJSON(&f)

	//if f.IsPublic == nil {
	//	*f.IsPublic = true
	//}

	if err != nil {
		//transletError := exceptions.Translate(validate, err)
		f.errRet(c, 500, err.Error())
		return
	}
	if f.ID == "" {
		f.ID = f.Name
	}
	ret, err := flavors.Create(serverClient, flavors.CreateOptsBuilder(
		&f,
	)).Extract()
	if err != nil {
		var errorDetail exceptions.ServerErrorDetails
		extractErr, code := exceptions.ServerExtractErrorInto(err, &errorDetail)
		c.JSON(code, extractErr)
		return
	}
	c.JSON(200, ret)
}

func (f Flavor) GetFlavors(c *gin.Context) {
	//imageClient := f.getClient()
	allParam := c.Request.URL.Query()
	fmt.Println(allParam)
	var listOpts flavors.ListOpts
	paramToMap := make(map[string]string)
	for key, value := range allParam {
		paramToMap[key] = value[0]
	}
	paramJson, err := json.Marshal(paramToMap)
	if err != nil {
		f.errRet(c, 500, err.Error())
	}
	err = json.Unmarshal(paramJson, &listOpts)
	if err != nil {
		f.errRet(c, 500, err.Error())
	}
	fmt.Println(listOpts)
	allImages, err := f.listFlavors(listOpts)
	if err != nil {
		f.errRet(c, 500, err.Error())
		return
	}
	c.JSON(200, allImages)
	return
}

func (f Flavor) listFlavors(opts flavors.ListOpts) ([]flavors.Flavor, error) {
	serverClient := f.getClient()
	allPagers, err := flavors.ListDetail(serverClient, flavors.ListOptsBuilder(opts)).AllPages()

	if err != nil {
		return nil, nil
	}
	allFlavors, err := flavors.ExtractFlavors(allPagers)

	return allFlavors, err
}

func (f Flavor) DelFlavors(c *gin.Context) {
	serverClient := f.getClient()
	flavorID := c.Param("flavor_id")
	err := flavors.Delete(serverClient, flavorID).ExtractErr()
	if err != nil {
		f.errRet(c, 401, err)
		return
	}
	c.JSON(202, nil)
}
